/**
 * COPYRIGHT HangZhou Trustway Technology Company Limited
 * All right reserved.
 */
package com.zfsmart.component.common.util;

import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.*;
import org.apache.http.conn.ClientConnectionManager;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.entity.ByteArrayEntity;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.springframework.util.StringUtils;

import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.nio.charset.Charset;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

/**
 * @Description get post(form/string/strem) put(string/stream) delate 方法
 * @Author 薛铁琪
 * @CreateTime 2019-03-11 22:09
 * @Version 1.0
 */
@Slf4j
public class HttpUtils {

    /**
     * 缺省编码
     */
    private final static String DEFAULT_CHARSET = "utf-8";
    /**
     * 连接超时时间
     */
    private final static int DEFALUT_CONNECT_TIMEOUT = 15000;

    /**
     * 读超时
     */
    private final static int DEFAULT_SOCKET_TIMEOUT = 30000;

    /**
     * Http Get
     *
     * @param url
     * @param params
     * @return
     */
    public static String doGet(String url, Map<String, String> params) throws IOException {
        return doGet(url, params, null, DEFAULT_CHARSET, DEFALUT_CONNECT_TIMEOUT, DEFAULT_SOCKET_TIMEOUT);
    }

    /**
     * Http Get
     *
     * @param url
     * @param params
     * @return
     */
    public static String doGet(String url, Map<String, String> params, Map<String, String> headers) throws IOException {
        return doGet(url, params, headers, DEFAULT_CHARSET, DEFALUT_CONNECT_TIMEOUT, DEFAULT_SOCKET_TIMEOUT);
    }

    /**
     * Http Post
     *
     * @param url
     * @param params
     * @return
     */
    public static String doPost(String url, Map<String, String> params) throws IOException {
        return doPost(url, params, null, DEFAULT_CHARSET, DEFALUT_CONNECT_TIMEOUT, DEFAULT_SOCKET_TIMEOUT);
    }

    /**
     * Http Post
     *
     * @param url
     * @param params
     * @return
     */
    public static String doPost(String url, Map<String, String> params, Map<String, String> headers) throws IOException {
        return doPost(url, params, null, DEFAULT_CHARSET, DEFALUT_CONNECT_TIMEOUT, DEFAULT_SOCKET_TIMEOUT);
    }

    /**
     * Http Get
     *
     * @param url
     * @param params
     * @param headers
     * @param charset
     * @param connectTimeout
     * @param socketTimeout
     * @return
     * @throws IOException
     */
    public static String doGet(String url, Map<String, String> params, Map<String, String> headers, String charset, int connectTimeout, int socketTimeout) throws IOException {
        CloseableHttpClient httpClient = HttpClients.createDefault();
        try {
            HttpGet httpGet = new HttpGet(buildGetUrl(url, params, charset));
            RequestConfig config = RequestConfig.custom()
                    .setConnectTimeout(connectTimeout)
                    .setSocketTimeout(socketTimeout).build();
            httpGet.setConfig(config);
            addHeaders(httpGet, headers);
            HttpResponse response = httpClient.execute(httpGet);
            if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
                throw new ClientProtocolException("status code=" + response.getStatusLine().getStatusCode());
            }
            String result = read(response, charset);
            return result;
        } finally {
            try {
                httpClient.close();
            } catch (IOException e) {
            }
        }
    }

    /**
     * 生成Http GET url
     *
     * @param url
     * @param parameters
     * @return
     * @throws IOException
     */
    private static String buildGetUrl(String url, Map<String, String> parameters, String encoding) throws IOException {
        if (org.apache.commons.lang3.StringUtils.isBlank(url)) {
            throw new IOException("url is empty!");
        }

        StringBuilder sb = new StringBuilder();
        if ((null != parameters) && !parameters.isEmpty()) {
            for (Entry<String, String> entry : parameters.entrySet()) {
                sb.append("&")
                        .append(entry.getKey())
                        .append("=")
                        .append((null != entry.getValue()) ? URLEncoder.encode(entry.getValue(), encoding) : "");
            }
            sb.substring(1);
        }
        String queryString = sb.toString().trim();

        url = url.trim();
        if (!org.apache.commons.lang3.StringUtils.isBlank(queryString)) {
            if (url.endsWith("?")) {
                url = url + queryString;
            } else {
                url = url + "?" + queryString;
            }
        }
        return url;
    }

    /**
     * @param @param  host
     * @param @param  path
     * @param @param  headers
     * @param @param  querys
     * @param @param  connectTimeout
     * @param @param  socketTimeout
     * @param @param  charset
     * @param @return 设定文件
     * @return HttpResponse 返回类型
     * @throws
     * @Title: doGet
     * @Description: TODO(这里用一句话描述这个方法的作用)
     */
    public static String doGet(String host, String path, Map<String, String> headers, Map<String, String> querys,
                               int connectTimeout, int socketTimeout, String charset) {
        connectTimeout = connectTimeout == 0 ? DEFALUT_CONNECT_TIMEOUT : connectTimeout;
        socketTimeout = socketTimeout == 0 ? DEFAULT_SOCKET_TIMEOUT : socketTimeout;
        charset = (StringUtils.isEmpty(charset) || charset == null) ? DEFAULT_CHARSET : charset;
        // 创建httpclient
        CloseableHttpClient httpClient = wrapClient(host);
        // 创建get请求
        String url = buildUrl(host, path, querys, charset);
        if (StringUtils.isEmpty(url) || url == null) {
            return null;
        }
        HttpGet request = new HttpGet(url);
        // 配置请求超时时间
        addTimeOut(request, connectTimeout, socketTimeout);
        // 配置请求头
        addHeaders(request, headers);

        // 发起请求
        return doRequest(httpClient, request, charset);
    }

    /**
     * @param @param  host
     * @param @param  path
     * @param @param  headers
     * @param @param  querys
     * @param @param  bodys
     * @param @param  connectTimeout
     * @param @param  socketTimeout
     * @param @param  charset
     * @param @return 设定文件
     * @return HttpResponse 返回类型
     * @throws
     * @Title: doPost
     * @Description: TODO(这里用一句话描述这个方法的作用)
     */
    public static String doPost(String host, String path, Map<String, String> headers, Map<String, String> querys,
                                Map<String, String> bodys, int connectTimeout, int socketTimeout, String charset) {
        connectTimeout = connectTimeout == 0 ? DEFALUT_CONNECT_TIMEOUT : connectTimeout;
        socketTimeout = socketTimeout == 0 ? DEFAULT_SOCKET_TIMEOUT : socketTimeout;
        charset = (StringUtils.isEmpty(charset) || charset == null) ? DEFAULT_CHARSET : charset;
        // 创建httpclient
        CloseableHttpClient httpClient = wrapClient(host);
        // 创建post请求
        String url = buildUrl(host, path, querys, charset);
        if (StringUtils.isEmpty(url) || url == null) {
            return null;
        }
        HttpPost request = new HttpPost(url);
        // 配置请求超时时间
        addTimeOut(request, connectTimeout, socketTimeout);
        // 配置请求头
        addHeaders(request, headers);
        // 配置post请求表单
        try {
            buildEntity(request, bodys, charset);
        } catch (UnsupportedEncodingException e) {
            log.debug("post request buildEntity error");
            e.printStackTrace();
            return null;
        }

        // 发起请求
        return doRequest(httpClient, request, charset);
    }

    /**
     * @param @param  host
     * @param @param  path
     * @param @param  headers
     * @param @param  querys
     * @param @param  bodys
     * @param @param  connectTimeout
     * @param @param  socketTimeout
     * @param @param  charset
     * @param @return 设定文件
     * @return HttpResponse 返回类型
     * @throws
     * @Title: doPost
     * @Description: TODO(这里用一句话描述这个方法的作用)
     */
    public static String doPost(String host, String path, Map<String, String> headers, Map<String, String> querys,
                                String bodys, int connectTimeout, int socketTimeout, String charset) {
        connectTimeout = connectTimeout == 0 ? DEFALUT_CONNECT_TIMEOUT : connectTimeout;
        socketTimeout = socketTimeout == 0 ? DEFAULT_SOCKET_TIMEOUT : socketTimeout;
        charset = (StringUtils.isEmpty(charset) || charset == null) ? DEFAULT_CHARSET : charset;
        // 创建httpclient
        CloseableHttpClient httpClient = wrapClient(host);
        // 创建post请求
        String url = buildUrl(host, path, querys, charset);
        if (StringUtils.isEmpty(url) || url == null) {
            return null;
        }
        HttpPost request = new HttpPost(url);
        // 配置请求超时时间
        addTimeOut(request, connectTimeout, socketTimeout);
        // 配置请求头
        addHeaders(request, headers);
        buildPostStringEntity(request, bodys, charset);

        // 发起请求
        return doRequest(httpClient, request, charset);
    }

    /**
     * @param @param  host
     * @param @param  path
     * @param @param  headers
     * @param @param  querys
     * @param @param  bodys
     * @param @param  connectTimeout
     * @param @param  socketTimeout
     * @param @param  charset
     * @param @return 设定文件
     * @return HttpResponse 返回类型
     * @throws
     * @Title: doPost
     * @Description: TODO(这里用一句话描述这个方法的作用)
     */
    public static String doPost(String host, String path, Map<String, String> headers, Map<String, String> querys,
                                byte[] bodys, int connectTimeout, int socketTimeout, String charset) {
        connectTimeout = connectTimeout == 0 ? DEFALUT_CONNECT_TIMEOUT : connectTimeout;
        socketTimeout = socketTimeout == 0 ? DEFAULT_SOCKET_TIMEOUT : socketTimeout;
        charset = (StringUtils.isEmpty(charset) || charset == null) ? DEFAULT_CHARSET : charset;
        // 创建httpclient
        CloseableHttpClient httpClient = wrapClient(host);
        // 创建post请求
        String url = buildUrl(host, path, querys, charset);
        if (StringUtils.isEmpty(url) || url == null) {
            return null;
        }
        HttpPost request = new HttpPost(url);
        // 配置请求超时时间
        addTimeOut(request, connectTimeout, socketTimeout);
        // 配置请求头
        addHeaders(request, headers);
        buildPostStreamEntity(request, bodys, charset);

        // 发起请求
        return doRequest(httpClient, request, charset);
    }

    /**
     * @param @param  host
     * @param @param  path
     * @param @param  method
     * @param @param  headers
     * @param @param  querys
     * @param @param  bodys
     * @param @param  connectTimeout
     * @param @param  socketTimeout
     * @param @param  charset
     * @param @return 设定文件
     * @return HttpResponse 返回类型
     * @throws
     * @Title: doPut
     * @Description: TODO(这里用一句话描述这个方法的作用)
     */
    public static String doPut(String host, String path, String method, Map<String, String> headers,
                               Map<String, String> querys, String bodys, int connectTimeout, int socketTimeout, String charset) {
        connectTimeout = connectTimeout == 0 ? DEFALUT_CONNECT_TIMEOUT : connectTimeout;
        socketTimeout = socketTimeout == 0 ? DEFAULT_SOCKET_TIMEOUT : socketTimeout;
        charset = (StringUtils.isEmpty(charset) || charset == null) ? DEFAULT_CHARSET : charset;
        // 创建httpclient
        CloseableHttpClient httpClient = wrapClient(host);
        // 创建post请求
        String url = buildUrl(host, path, querys, charset);
        if (StringUtils.isEmpty(url) || url == null) {
            return null;
        }
        HttpPut request = new HttpPut(url);
        // 配置请求超时时间
        addTimeOut(request, connectTimeout, socketTimeout);
        // 配置请求头
        addHeaders(request, headers);
        buildPutStringEntity(request, bodys, charset);

        // 发起请求
        return doRequest(httpClient, request, charset);
    }

    /**
     * @param @param  host
     * @param @param  path
     * @param @param  method
     * @param @param  headers
     * @param @param  querys
     * @param @param  bodys
     * @param @param  connectTimeout
     * @param @param  socketTimeout
     * @param @param  charset
     * @param @return 设定文件
     * @return HttpResponse 返回类型
     * @throws
     * @Title: doPut
     * @Description: TODO(这里用一句话描述这个方法的作用)
     */
    public static String doPut(String host, String path, String method, Map<String, String> headers,
                               Map<String, String> querys, byte[] bodys, int connectTimeout, int socketTimeout, String charset) {
        connectTimeout = connectTimeout == 0 ? DEFALUT_CONNECT_TIMEOUT : connectTimeout;
        socketTimeout = socketTimeout == 0 ? DEFAULT_SOCKET_TIMEOUT : socketTimeout;
        charset = (StringUtils.isEmpty(charset) || charset == null) ? DEFAULT_CHARSET : charset;
        // 创建httpclient
        CloseableHttpClient httpClient = wrapClient(host);
        // 创建post请求
        String url = buildUrl(host, path, querys, charset);
        if (StringUtils.isEmpty(url) || url == null) {
            return null;
        }
        HttpPut request = new HttpPut(url);
        // 配置请求超时时间
        addTimeOut(request, connectTimeout, socketTimeout);
        // 配置请求头
        addHeaders(request, headers);
        buildPutStreamEntity(request, bodys, charset);

        // 发起请求
        return doRequest(httpClient, request, charset);
    }

    /**
     * @param @param  host
     * @param @param  path
     * @param @param  method
     * @param @param  headers
     * @param @param  querys
     * @param @param  connectTimeout
     * @param @param  socketTimeout
     * @param @param  charset
     * @param @return 设定文件
     * @return HttpResponse 返回类型
     * @throws
     * @Title: doDelete
     * @Description: TODO(这里用一句话描述这个方法的作用)
     */
    public static String doDelete(String host, String path, String method, Map<String, String> headers,
                                  Map<String, String> querys, int connectTimeout, int socketTimeout, String charset) {
        connectTimeout = connectTimeout == 0 ? DEFALUT_CONNECT_TIMEOUT : connectTimeout;
        socketTimeout = socketTimeout == 0 ? DEFAULT_SOCKET_TIMEOUT : socketTimeout;
        charset = (StringUtils.isEmpty(charset) || charset == null) ? DEFAULT_CHARSET : charset;
        // 创建httpclient
        CloseableHttpClient httpClient = wrapClient(host);
        // 创建get请求
        String url = buildUrl(host, path, querys, charset);
        if (StringUtils.isEmpty(url) || url == null) {
            return null;
        }
        HttpDelete request = new HttpDelete(url);
        // 配置请求超时时间
        addTimeOut(request, connectTimeout, socketTimeout);
        // 配置请求头
        addHeaders(request, headers);

        // 发起请求
        return doRequest(httpClient, request, charset);
    }

    private static String buildUrl(String host, String path, Map<String, String> querys, String encoding) {
        if (StringUtils.isEmpty(host)) {
            log.debug("host is empty!");
            return null;
        }
        StringBuilder sbUrl = new StringBuilder();
        sbUrl.append(host);
        if (!StringUtils.isEmpty(path)) {
            sbUrl.append(path);
        }
        StringBuilder sb = new StringBuilder();
        if ((null != querys) && !querys.isEmpty()) {
            for (Entry<String, String> entry : querys.entrySet()) {
                try {
                    sb.append("&").append(entry.getKey()).append("=").append(
                            (null != entry.getValue()) ? URLEncoder.encode(entry.getValue(), encoding) : "");
                } catch (UnsupportedEncodingException e) {
                    log.debug("key-value {} {} encode{} error", entry.getKey(), entry.getValue());
                    e.printStackTrace();
                    return null;
                }

            }
        }
        String queryString = "";
        if (sb.length() > 0) {
            queryString = sb.substring(1).toString().trim();
        }
        String url = sbUrl.toString().trim();
        if (!StringUtils.isEmpty(queryString)) {
            if (url.endsWith("?")) {
                url = url + queryString;
            } else {
                url = url + "?" + queryString;
            }
        }
        return url;
    }

    private static void buildEntity(HttpPost httpPost, Map<String, String> parameters, String encoding)
            throws UnsupportedEncodingException {
        List<NameValuePair> params = new ArrayList<NameValuePair>();
        if ((null != parameters) && !parameters.isEmpty()) {
            for (Entry<String, String> entry : parameters.entrySet()) {
                params.add(new BasicNameValuePair(entry.getKey(), (null != entry.getValue()) ? entry.getValue() : ""));
            }
        }
        UrlEncodedFormEntity entity = new UrlEncodedFormEntity(params, encoding);
        httpPost.setEntity(entity);
    }

    private static void buildPostStringEntity(HttpPost httpPost, String body, String encoding) {
        if (!StringUtils.isEmpty(body)) {
            StringEntity entity = new StringEntity(body, encoding);
            httpPost.setEntity(entity);
        }
    }

    private static void buildPostStreamEntity(HttpPost httpPost, byte[] body, String encoding) {
        if (body != null) {
            httpPost.setEntity(new ByteArrayEntity(body));
        }
    }

    private static void buildPutStringEntity(HttpPut httpPost, String body, String encoding) {
        if (!StringUtils.isEmpty(body)) {
            StringEntity entity = new StringEntity(body, encoding);
            httpPost.setEntity(entity);
        }
    }

    private static void buildPutStreamEntity(HttpPut httpPost, byte[] body, String encoding) {
        if (body != null) {
            httpPost.setEntity(new ByteArrayEntity(body));
        }
    }

    private static void addTimeOut(HttpRequestBase request, int connectTimeout, int socketTimeout) {
        RequestConfig config = RequestConfig.custom().setConnectTimeout(connectTimeout).setSocketTimeout(socketTimeout)
                .build();
        request.setConfig(config);
    }

    private static void addHeaders(HttpRequestBase request, Map<String, String> headers) {
        if (headers != null) {
            for (String key : headers.keySet()) {
                request.addHeader(key, headers.get(key));
            }
        }
    }

    private static CloseableHttpClient wrapClient(String host) {
        CloseableHttpClient httpClient = new DefaultHttpClient();// HttpClients.createDefault();不支持ssl
        if (host.startsWith("https://")) {
            sslClient(httpClient);
        }

        return httpClient;
    }

    private static void sslClient(CloseableHttpClient httpClient) {
        try {
            SSLContext ctx = SSLContext.getInstance("TLS");
            X509TrustManager tm = new X509TrustManager() {

                public X509Certificate[] getAcceptedIssuers() {
                    return null;
                }

                public void checkClientTrusted(X509Certificate[] xcs, String str) {

                }

                public void checkServerTrusted(X509Certificate[] xcs, String str) {

                }
            };
            ctx.init(null, new TrustManager[]{tm}, null);
            SSLSocketFactory ssf = new SSLSocketFactory(ctx);
            ssf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
            ClientConnectionManager ccm = httpClient.getConnectionManager();
            SchemeRegistry registry = ccm.getSchemeRegistry();
            registry.register(new Scheme("https", 443, ssf));
        } catch (KeyManagementException ex) {
            throw new RuntimeException(ex);
        } catch (NoSuchAlgorithmException ex) {
            throw new RuntimeException(ex);
        }
    }

    private static String doRequest(CloseableHttpClient httpClient, HttpRequestBase request, String encoding) {
        // 发起请求
        try {
            HttpResponse response = httpClient.execute(request);
            if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
                log.debug("status code={}", response.getStatusLine().getStatusCode());
                return null;
            }
            StringBuilder sb = new StringBuilder();
            Charset charset = ContentType.getOrDefault(response.getEntity()).getCharset();
            if (charset == null) {
                charset = Charset.forName(encoding);
            }
            InputStream is = response.getEntity().getContent();
            InputStreamReader inputStreamReader = new InputStreamReader(is, charset);
            BufferedReader reader = new BufferedReader(inputStreamReader);
            String s;
            while (((s = reader.readLine()) != null)) {
                sb.append(s);
            }
            reader.close();
            return sb.toString();
        } catch (ClientProtocolException e) {
            e.printStackTrace();
            return null;
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        } finally {
            try {
                httpClient.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }

    /**
     * Http POST
     *
     * @param url
     * @param content
     * @param headers
     * @param charset
     * @return
     * @throws IOException
     */
    public static String doPost(String url, String content, Map<String, String> headers, String charset) throws IOException {
        return doPost(url, content, headers, charset, DEFALUT_CONNECT_TIMEOUT, DEFAULT_SOCKET_TIMEOUT);
    }

    /**
     * Http POST(发送String内容)
     *
     * @param url
     * @param content
     * @param headers
     * @param charset
     * @param connectTimeout
     * @param socketTimeout
     * @return
     * @throws IOException
     */
    public static String doPost(String url, String content, Map<String, String> headers, String charset, int connectTimeout, int socketTimeout) throws IOException {
        CloseableHttpClient httpClient = HttpClients.createDefault();
        try {
            HttpPost httpPost = new HttpPost(url);
            RequestConfig config = RequestConfig.custom()
                    .setConnectTimeout(connectTimeout)
                    .setSocketTimeout(socketTimeout).build();
            httpPost.setConfig(config);
            addHeaders(httpPost, headers);
            StringEntity entity = new StringEntity(content, charset);
            httpPost.setEntity(entity);
            HttpResponse response = httpClient.execute(httpPost);
            if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
                throw new ClientProtocolException("status code=" + response.getStatusLine().getStatusCode());
            }

            String result = read(response, charset);

            if (log.isDebugEnabled()) {
                log.debug("response={}", result);
            }

            return result;

        } finally {
            try {
                httpClient.close();
            } catch (IOException e) {
            }
        }
    }

    public static String doPostByJson(String url, String content, Map<String, String> headers) throws IOException {
        CloseableHttpClient httpClient = HttpClients.createDefault();
        try {
            HttpPost httpPost = new HttpPost(url);
            RequestConfig config = RequestConfig.custom()
                    .setConnectTimeout(DEFALUT_CONNECT_TIMEOUT)
                    .setSocketTimeout(DEFAULT_SOCKET_TIMEOUT).build();
            httpPost.setConfig(config);
            addHeaders(httpPost, headers);
            StringEntity entity = new StringEntity(content, DEFAULT_CHARSET);
            httpPost.addHeader("Content-Type", "application/json");
            httpPost.setEntity(entity);
            HttpResponse response = httpClient.execute(httpPost);
            if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
                throw new ClientProtocolException("status code=" + response.getStatusLine().getStatusCode());
            }

            String result = read(response, DEFAULT_CHARSET);

            if (log.isDebugEnabled()) {
                log.debug("response={}", result);
            }

            return result;

        } finally {
            try {
                httpClient.close();
            } catch (IOException e) {
            }
        }
    }

    /**
     * Http Post
     *
     * @param url
     * @param params
     * @return
     */
    public static String doPost(String url, Map<String, String> params, Map<String, String> headers, String charset, int connectTimeout, int socketTimeout) throws IOException {
        CloseableHttpClient httpClient = HttpClients.createDefault();
        try {
            HttpPost httpPost = new HttpPost(url);
            RequestConfig config = RequestConfig.custom()
                    .setConnectTimeout(connectTimeout)
                    .setSocketTimeout(socketTimeout).build();
            buildEntity(httpPost, params, charset);
            httpPost.setConfig(config);
            addHeaders(httpPost, headers);
            HttpResponse response = httpClient.execute(httpPost);
            if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
                throw new ClientProtocolException("status code=" + response.getStatusLine().getStatusCode());
            }

            String result = read(response, charset);
            return result;

        } finally {
            try {
                httpClient.close();
            } catch (IOException e) {
            }
        }
    }

    /**
     * 从http entity中读取内容
     *
     * @param response
     * @return
     * @throws IOException
     * @throws UnsupportedEncodingException
     * @Param encoding
     */
    private static String read(HttpResponse response, String encoding) throws IOException, UnsupportedEncodingException {
        StringBuilder sb = new StringBuilder();
        Charset charset = ContentType.getOrDefault(response.getEntity()).getCharset();
        if (charset == null) {
            charset = Charset.forName(encoding);
        }
        InputStream is = response.getEntity().getContent();
        InputStreamReader inputStreamReader = new InputStreamReader(is, charset);
        BufferedReader reader = new BufferedReader(inputStreamReader);
        String s;
        while (((s = reader.readLine()) != null)) {
            sb.append(s);
        }
        reader.close();

        return sb.toString();
    }

    /**
     * 下载文件
     *
     * @param res
     * @param fileUrl
     * @return
     */
    public static byte[] downLoadFileHttp(String fileUrl) {
        URL httpurl;
        try {
            httpurl = new URL(fileUrl);
            HttpURLConnection httpConn = (HttpURLConnection) httpurl.openConnection();
            httpConn.setDoOutput(false);// 使用 URL 连接进行输出
            httpConn.setDoInput(true);// 使用 URL 连接进行输入
            httpConn.setUseCaches(false);// 忽略缓存
            httpConn.setRequestMethod("GET");// 设置URL请求方法
            httpConn.setConnectTimeout(20 * 1000); //设置连接超时
            httpConn.setReadTimeout(20 * 1000); //设置读取超时
            //可设置请求头
            httpConn.setRequestProperty("Connection", "Keep-Alive");// 维持长连接
            httpConn.setRequestProperty("Charset", "UTF-8");
            //可设置请求头
            return input2byte(httpConn.getInputStream());
        } catch (Exception e) {
            log.error("HttpURLConnection error", e);
            return null;
        }
    }

    public static final byte[] input2byte(InputStream inStream)
            throws IOException {
        ByteArrayOutputStream swapStream = new ByteArrayOutputStream();
        byte[] buff = new byte[100];
        int rc = 0;
        while ((rc = inStream.read(buff, 0, 100)) > 0) {
            swapStream.write(buff, 0, rc);
        }
        byte[] in2b = swapStream.toByteArray();
        return in2b;
    }
}

